//
//  main.cpp
//  graphics
//
//  Created by 刘文栖 on 2018/3/9.
//  Copyright © 2018年 刘文栖. All rights reserved.
//

//#include <stdio.h>
//#define N 4
//int Tree[N];

//int findRoot(int x){
//    if(Tree[x] == -1) return x;
//    else return findRoot(Tree[x]);
//}
//int findRoot(int x){//路径压缩优化
//    if(Tree[x] == -1) return x;
//    else {
//        int tmp = findRoot(Tree[x]);
//        Tree[x] = tmp;
//        return tmp;
//    }
//}

//int main() {
//    Tree[0] = -1, Tree[1] = 0, Tree[2] = 1, Tree[3] = 2;
//    printf("%d\n", findRoot(3));
//    for (int i=0; i<N; i++) {
//        printf("%d\n", Tree[i]);
//    }
//    // insert code here...
//    return 0;
//}

////畅通工程
//#include <stdio.h>
//using namespace std;
//#define N 1000
//int Tree[N];
//int findRoot(int x){
//    if(Tree[x] == -1) return x;
//    else {
//        int tmp = findRoot(Tree[x]);
//        Tree[x] = tmp;
//        return tmp;
//    }
//}
//int main(){
//    int n, m;
//    while(scanf("%d", &n) != EOF && n != 0) {
//        scanf("%d", &m);
//        for(int i=1; i<=n; i++) Tree[i] = -1;
//        while(m-- != 0){
//            int a, b;
//            scanf("%d%d", &a, &b);
//            a = findRoot(a);
//            b = findRoot(b);
//            if(a != b) Tree[a] = b;
//        }
//        int ans = 0;
//        for(int i=1; i<=n; i++){
//            if(Tree[i] == -1) ans++;
//        }
//        printf("%d\n", ans-1);
//    }
//}

////More is better
//#include <stdio.h>
//using namespace std;
//#define N 10000001
//int Tree[N];
//int findRoot(int x){
//    if(Tree[x] == -1) return x;
//    else {
//        int tmp = findRoot(Tree[x]);
//        Tree[x] = tmp;
//        return tmp;
//    }
//}
//int sum[N];
//int main(){
//    int n;
//    while(scanf("%d", &n) != EOF) {
//        for(int i=1; i<N; i++){
//            Tree[i] = -1;
//            sum[i] = 1;
//        }
//        while(n-- != 0){
//            int a, b;
//            scanf("%d%d", &a, &b);
//            a = findRoot(a);
//            b = findRoot(b);
//            if(a != b) {
//                Tree[a] = b;
//                sum[b] += sum[a];
//            }
//        }
//        int ans = 1;
//        for(int i=1; i<N; i++){
//            if(Tree[i] == -1 && sum[i] > ans) ans = sum[i];
//        }
//        printf("%d\n", ans);
//    }
//}

//最小生成树 MST

////还是畅通工程
//#include <stdio.h>
//#include <algorithm>
//using namespace std;
//#define N 101
//int Tree[N];
//int findRoot(int x){
//    if(Tree[x] == -1) return x;
//    else {
//        int tmp = findRoot(Tree[x]);
//        Tree[x] = tmp;
//        return tmp;
//    }
//}
//struct Edge {
//    int a, b;
//    int cost;
//    bool operator < (const Edge &A) const {
//        return cost < A.cost;
//    }
//}edge[6000];
//int main(){
//    int n;
//    while(scanf("%d", &n) != EOF && n != 0) {
//        for(int i=1; i<=n*(n-1)/2; i++){
//            scanf("%d%d%d", &edge[i].a, &edge[i].b, &edge[i].cost);
//        }
//        sort(edge+1, edge+1+n*(n-1)/2);
//        for(int i=1; i<=n; i++) Tree[i] = -1;
//        int ans = 0;
//        for(int i=1; i<=n*(n-1)/2; i++) {
//            int a = findRoot(edge[i].a);
//            int b = findRoot(edge[i].b);
//            if(a != b){
//                Tree[a] = b;
//                ans += edge[i].cost;
//            }
//        }
//        printf("%d\n", ans);
//    }
//}

////Freckles
//#include <stdio.h>
//#include <math.h>
//#include <algorithm>
//using namespace std;
//#define N 101
//int Tree[N];
//int findRoot(int x){
//    if(Tree[x] == -1) return x;
//    else {
//        int tmp = findRoot(Tree[x]);
//        Tree[x] = tmp;
//        return tmp;
//    }
//}
//struct Edge {
//    int a, b;
//    double cost;
//    bool operator < (const Edge &A) const {
//        return cost < A.cost;
//    }
//}edge[6000];
//struct Point {
//    double x, y;
//    double getDistance(Point A) {
//        double tmp = (x - A.x)*(x - A.x) + (y - A.y)*(y - A.y);
//        return sqrt(tmp);
//    }
//}list[101];
//int main(){
//    int n;
//    while(scanf("%d", &n) != EOF){
//        for(int i=1; i<=n; i++){
//            scanf("%lf%lf", &list[i].x, &list[i].y);
//        }
//        int size = 0;
//        for(int i=1; i<=n; i++){
//            for(int j=1; j<=n; j++){
//                edge[size].a = i;
//                edge[size].b = j;
//                edge[size].cost = list[i].getDistance(list[j]);
//                size++;
//            }
//        }
//        sort(edge, edge+size);
//        for(int i=0; i<size; i++){
//            Tree[i] = -1;
//        }
//        double ans = 0;
//        for(int i=0; i<size; i++){
//            int a = findRoot(edge[i].a);
//            int b = findRoot(edge[i].b);
//            if(a != b){
//                Tree[a] = b;
//                ans += edge[i].cost;
//            }
//        }
//        printf("%2lf\n", ans);
//    }
//}

////最短路径
//#include <stdio.h>
//int ans[101][101];
//int main(){
//    int n, m;
//    while(scanf("%d%d", &n, &m) != EOF) {
//        if(n == 0 && m == 0) break;
//        for(int i=1; i<=n; i++){
//            for(int j=1; j<=n; j++){
//                ans[i][j] = -1;
//            }
//            ans[i][i] = 0;
//        }
//        while(m--){
//            int a, b, c;
//            scanf("%d%d%d", &a, &b, &c);
//            ans[a][b] = ans[b][a] = c;
//        }
//        for(int k=1; k<=n; k++){
//            for(int i=1; i<=n; i++){
//                for(int j=1; j<=n; j++){
//                    if(ans[i][k] == -1 || ans[k][j] == -1) continue;
//                    if(ans[i][j] == -1 || ans[i][k] + ans[k][j] < ans[i][j])
//                        ans[i][j] = ans[i][k] + ans[k][j];
//                }
//            }
//        }
//        printf("%d\n", ans[1][n]);
//    }
//}

////例5.6
//#include <stdio.h>
//#include <vector>
//using namespace std;
//struct E{
//    int next;
//    int c;
//};
//vector<E> edge[101];
//bool mark[101];
//int Dis[101];
//int main(){
//    int n, m;
//    while(scanf("%d%d", &n, &m) != EOF){
//        if(n == 0 && m == 0) break;
//        for(int i=1; i<=n; i++) edge[i].clear();
//        while(m--){
//            int a, b, c;
//            scanf("%d%d%d", &a, &b, &c);
//            E tmp;
//            tmp.c = c;
//            tmp.next = b;
//            edge[a].push_back(tmp);
//            tmp.next = a;
//            edge[b].push_back(tmp);
//        }
//        for(int i=1; i<=n; i++){
//            Dis[i] = -1;
//            mark[i] = false;
//        }
//        Dis[1] = 0;
//        mark[1] = true;
//        int newP = 1;
//        for(int i=1; i<=n; i++){
//            for(int j=0; j<edge[newP].size(); j++){
//                int t = edge[newP][j].next;
//                int c = edge[newP][j].c;
//                if(mark[t] == true) continue;
//                if(Dis[t] == -1 || Dis[t] > Dis[newP] + c) Dis[t] = Dis[newP] + c;
//            }
//            int min = 123123123;
//            for(int j=1; j<=n; j++){
//                if(mark[j] == true) continue;
//                if(Dis[j] == -1) continue;
//                if(Dis[j] < min){
//                    min = Dis[j];
//                    newP = j;
//                }
//            }
//            mark[newP] = true;
//        }
//        printf("%d\n", Dis[n]);
//    }
//}

////例题5.6 最短路径问题
//#include <stdio.h>
//#include <vector>
//using namespace std;
//struct E {
//    int next;
//    int c;
//    int cost;
//};
//vector<E> edge[1001];
//int Dis[1001];
//int cost[1001];
//bool mark[1001];
//int main(){
//    int n, m;
//    int S,T;
//    while(scanf("%d%d", &n, &m) != EOF){
//        if(n == 0 && m == 0) break;
//        for(int i=1; i<=n; i++) edge[i].clear();
//        while(m--){
//            int a, b, c, cost;
//            scanf("%d%d%d%d", &a, &b, &c, &cost);
//            E tmp;
//            tmp.c = c;
//            tmp.cost = cost;
//            tmp.next = b;
//            edge[a].push_back(tmp);
//            tmp.next = a;
//            edge[b].push_back(tmp);
//        }
//        scanf("%d%d", &S, &T);
//        for(int i=1; i<=n; i++){
//            Dis[i] = -1;
//            mark[i] = false;
//        }
//        Dis[S] = 0;
//        mark[S] = true;
//        int newP = S;
//        for(int i=1; i<=n; i++){
//            for(int j=0; j<edge[newP].size(); j++){
//                int t=edge[newP][j].next;
//                int c=edge[newP][j].c;
//                int co=edge[newP][j].cost;
//                if(mark[t] == true) continue;
//                if(Dis[t] == -1 || Dis[t]>Dis[newP]+c || Dis[t] == Dis[newP]+c && cost[t] > cost[newP] + co){
//                    Dis[t] = Dis[newP]+c;
//                    cost[t] = cost[newP]+co;
//                }
//            }
//            int min=123123123;
//            for(int j=1; j<=n; j++){
//                if(mark[j] == true) continue;
//                if(Dis[j] == -1) continue;
//                if(Dis[j] < min){
//                    min=Dis[j];
//                    newP=j;
//                }
//            }
//            mark[newP]=true;
//        }
//        printf("%d %d\n", Dis[T], cost[T]);
//    }
//}

//拓扑排序
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
vector<int> edge[501];
queue<int> Q;
int main(){
    int inDegree[501];
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        if(n == 0 && m == 0) break;
        for(int i=0; i<n; i++){
            inDegree[i] = 0;
            edge[i].clear();
        }
        while(m--){
            int a, b;
            scanf("%d%d", &a, &b);
            inDegree[b]++;
            edge[a].push_back(b);
        }
        while(Q.empty() == false) Q.pop();
        for(int i=0; i<n; i++){
            if(inDegree[i] == 0) Q.push(i);
        }
        int cnt=0;
        while(Q.empty() == false){
            int nowP = Q.front();
            Q.pop();
            cnt++;
            for(int i=0; i<edge[nowP].size(); i++){
                inDegree[edge[nowP][i]]--;
                if(inDegree[edge[nowP][i]] == 0){
                    Q.push(edge[nowP][i]);
                }
            }
        }
        if(cnt == n) puts("YES");
        else puts("NO");
    }
}
























